package org.tulkas.config;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Properties;

import org.junit.Test;

/**
 * @author <a href="mailto:tulkas.web@gmail.com">Tulkas</a>
 *
 */
public class ConfigTest {

	@Test
	public void testDefault() throws Exception {
		BasicConfig config = new BasicConfig();
		InputStream is = this.getClass().getClassLoader().getResourceAsStream(
				"org/tulkas/util/test/res/default.properties");
		config.load(is);
		is.close();

		String[] keys = config.getAllKeys();
		assertTrue(keys.length > 10);

		assertEquals(true, config.getBoolean("internet.options.cookie.enabled",
				false));
		assertEquals(1, config.getInt("flusher.manager.interval"));
		assertEquals(1l, config.getLong("flusher.manager.interval"));
		assertEquals(0.1f, config.getFloat("cache.config.heuristicCoefficient",
				0.2f), 0.01f);
		assertEquals(0.1f,
				config.getFloat("cache.config.heuristicCoefficient"), 0.01f);
		assertEquals(0.1,
				config.getDouble("cache.config.heuristicCoefficient"), 0.01);
		assertEquals("UTF-8", config.getString(
				"internet.options.defaultCharset", "GBK"));
		assertEquals(null, config.getString("internet.options.proxyHost"));
		assertEquals(null, config.getValue("internet.options.proxyHost"));

		assertEquals(true, config.getBoolean("aaa", true));
		assertEquals(false, config.getBoolean("aaa"));
		assertEquals(2, config.getInt("bbb", 2));
		assertEquals(33, config.getLong("ccc", 33l));
		assertEquals(0.2f, config.getFloat("ddd", 0.2f), 0.01f);
		assertEquals(0.2, config.getDouble("eee", 0.2), 0.01);
		assertEquals("GBK", config.getString("fff", "GBK"));

		config.setValue("aaa.bbb.1", "11");
		config.setValue("aaa.bbb.2", "22");
		config.setValue("aaa.bbb.3", "33");

		assertTrue(config.containsKey("aaa.bbb.1"));
		assertTrue(config.containsKey("flusher.manager.interval"));
		assertFalse(config.containsKey("aaa.bbb.111"));

		Configuration config2 = config.getSubConfig("aaa.bbb.");
		assertEquals(3, config2.getAllKeys().length);
		assertEquals("11", config2.getValue("1"));

		Properties subProp = config.getSubProperties("aaa.bbb.");
		assertEquals(3, subProp.size());
		assertEquals("11", subProp.getProperty("1"));

		Properties prop = config.toProperties();
		assertEquals("11", prop.getProperty("aaa.bbb.1"));
		assertEquals(0.1f, Float.valueOf(prop
				.getProperty("cache.config.heuristicCoefficient")), 0.01f);

		config.remove("aaa.bbb.1");
		assertFalse(config.containsKey("aaa.bbb.1"));
	}

	@Test
	public void testParent() throws Exception {
		BasicConfig parent = new BasicConfig();
		InputStream is = this.getClass().getClassLoader().getResourceAsStream(
				"org/tulkas/util/test/res/default.properties");
		parent.load(is);
		is.close();

		assertEquals(26, parent.getAllKeys().length);

		BasicConfig config = new BasicConfig(parent);
		config.setValue("custom.key.key1", "111");
		config.setValue("custom.key.key2", "key2");
		config.setValue("custom.key.key3", "11.22");
		config.setValue("flusher.manager.interval", "2");
		assertEquals(4, config.getOwnKeys().length);
		assertEquals(3, config.getOwnKeys("custom.key").length);
		assertEquals(3, config.getAllKeys("custom.key").length);
		assertEquals(29, config.getAllKeys().length);
		assertEquals(2, config.getInt("flusher.manager.interval", 10));
		assertEquals(true, config.getBoolean("internet.options.cookie.enabled",
				false));
		assertEquals(true, config
				.containsKey("cache.config.heuristicCoefficient"));

		Properties prop2 = config.toProperties();
		assertEquals("2", prop2.getProperty("flusher.manager.interval"));
		assertEquals("111", prop2.getProperty("custom.key.key1"));

		BasicConfig nbc = new BasicConfig();
		nbc.setValues(prop2);
		assertEquals(28, nbc.getAllKeys().length);
		assertEquals("2", nbc.getString("flusher.manager.interval"));
		
		BasicConfig nbc2 = new BasicConfig();
		nbc2.setValues(nbc);
		assertEquals(28, nbc2.getAllKeys().length);
		assertEquals("2", nbc2.getString("flusher.manager.interval"));

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		config.save(baos);
		baos.close();
		byte[] bytes = baos.toByteArray();

		Properties props = new Properties();
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		props.load(bais);
		assertEquals(4, props.size());

		config.clear();
		assertEquals(26, config.getAllKeys().length);
	}

	@Test
	public void testKeyPart() throws Exception {
		assertEquals(true, BasicConfig.isAvailableKeyPart("Asdfal08__--"));
		assertEquals(true, BasicConfig.isAvailableKeyPart("_1909"));
		assertEquals(false, BasicConfig.isAvailableKeyPart("adsf asdf"));
		assertEquals(false, BasicConfig.isAvailableKeyPart("asdf.ads"));
		assertEquals(false, BasicConfig.isAvailableKeyPart("asdf=ads"));
		assertEquals(false, BasicConfig.isAvailableKeyPart("*&^$asdf098"));
	}
}
